#include "ws2812b.h"                  // Device header

#define WS_NUM (WS2812_MAX * (3*8) + 2)

uint16_t send_Buf[ WS_NUM ];
/**
 * @brief  ws2812设置颜色
 * @param  示例：WS_SetRGB( 1, 0xff, 0x00, 0xff );
 * @retval void
 */
void WS_SetRGB(uint8_t num, uint8_t R, uint8_t G, uint8_t B)
{
	int i;
	
	/* 输入限幅 */
	if( num > WS2812_MAX )
		return ;
	
	/* 绿色 */
	for(i = 0; i<8; i++) {
		if(G & (0x80>>i)) {
			send_Buf[(num*3*8) + i + 1] = WS_H;
		} else {
			send_Buf[(num*3*8) + i + 1] = WS_L;
		}
	}
	
	/* 红色 */
	for(i = 0; i<8; i++) {
		if(R & (0x80>>i)) {
			send_Buf[(num*3*8) + 8 + i + 1] = WS_H;
		} else {
			send_Buf[(num*3*8) + 8 + i + 1] = WS_L;
		}
	}
	
	/* 蓝色 */
	for(i = 0; i<8; i++) {
		if(B & (0x80>>i)) {
			send_Buf[(num*3*8) + 16 + i + 1] = WS_H;
		} else {
			send_Buf[(num*3*8) + 16 + i + 1] = WS_L;
		}
	}send_Buf[0] = 0;
}

/**
 * @brief  WS2812B设置二进制颜色
 * @retval 示例：WS_SetColor( 1, 0xff00ff );
 */
void WS_SetColor(uint8_t num, uint32_t color)
{
	WS_SetRGB(num, (color&0xff0000)>>16, (color&0x00ff00)>>8, (color&0x0000ff));
}

/**
 * @brief  WS2812B设置二进制颜色
 * @retval 示例：WS_SetColor( 1, "#ff00ff" );
 */
void WS_SetColors(uint8_t num, char * color)
{
	uint8_t R, G, B;
	uint8_t RGB[6];
	
	/* 转换颜色 */
	for(int i=1; i<7; i++)
	{
		if((color[i]<71 && color[i]>64) || (color[i]<58 && color[i]>47)) {	//如果全部符合要求
			if((color[i]<58 && color[i]>47)) {
				RGB[i-1] = color[i] - '0';
			} else {
				RGB[i-1] = color[i] - 'A' + 10;
			}
		} else if(color[i]<103 && color[i]>96){		//如果有小写
			RGB[i-2] = color[i] - 'a' + 10;
		} else {									//如果数据有误
			RGB[i] = 0;
		}
	}
	
	/* 颜色赋值 */
	R = (RGB[0]&0x0f)<<4|(RGB[1]&0x0f);
	G = (RGB[2]&0x0f)<<4|(RGB[3]&0x0f);
	B = (RGB[4]&0x0f)<<4|(RGB[5]&0x0f);
	
	/* 调用API */
	WS_SetRGB(num, R, G, B);
}

/**
 * @brief  WS2812B获取颜色
 * @retval 无
 */
uint32_t GetColor(uint8_t num)
{
	uint32_t i, ReColor = 0;
	uint8_t R=0x00, G=0x00, B=0x00;
	
	/* 蓝色 */
	for(i=0; i<8; i++) {
		if(send_Buf[num*3*8 + i + 1] == WS_H) {
			G |= 0x80>>i;
		}
	}
	
	for(i=0; i<8; i++) {
		if(send_Buf[num*3*8 + 8 + i + 1] == WS_H) {
			R |= 0x80>>i;
		}
	}
	
	for(i=0; i<8; i++) {
		if(send_Buf[num*3*8 + 16 + i + 1] == WS_H) {
			B |= 0x80>>i;
		}
	}
	
	ReColor = (R<<16)|(G<<8)|(B);
	return ReColor;
}

/**
 * @brief  WS2812B初始化
 * @retval 无
 */
void WS2812b_Init(void)
{
	/* 输出缓冲区填充BUFF */
	WS_Clear(0x000000);
	
	/* 开启一个定时器中断调用 ws_tick_inc() */
	HAL_TIM_Base_Start_IT(&htim3);
}

/**
 * @brief  发送一帧颜色数据
 * @param  void
 * @retval void
 */
void ws_tick_inc(void)
{
	/* 停止标志 */
	send_Buf[WS_NUM-1] = 0;
	
	/* PWM + DMA */
	HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_2, (uint32_t *)send_Buf, WS_NUM);
}

/**
 * @brief  WS2812B清屏
 * @retval 无
 */
void WS_Clear(uint32_t Color)
{
	int i;
	
	for( i = 0; i < WS2812_MAX; i++ )
	{
		WS_SetColor(i, Color);
	}
}

/******************* (C) COPYRIGHT 2022 FUYEBING*****END OF FILE************/
